﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WWDemon.Model;
using WatsonWebsocket;
using WWDemon.Log;

namespace WWDemon.Core.WebSocket
{
    public class WebSocketClient : IDisposable
    {
        public delegate Task SocketClose();

        public delegate Task SocketConnect(bool state);

        public delegate Task SockettReceive(CommondPC receiveData);

        public event SocketConnect OnConnect;
        public event SocketClose OnClose;
        public event SockettReceive OnReceive;

        private WatsonWsClient client;

        public WebSocketClient(string host,int prot)
        {
            client = new WatsonWsClient(host, prot,false);
            client.MessageReceived += Client_MessageReceived;
            client.ServerConnected += Client_ServerConnected;
            client.ServerDisconnected += Client_ServerDisconnected;
            client.KeepAliveInterval = 8;

        }

        private void Client_ServerDisconnected(object sender, EventArgs e)
        {
            try
            {
                if (OnClose != null)
                {
                    OnClose.Invoke();
                }
            }
            catch (Exception ex)
            {
                LogHelper.Log(LogDefine.LogError, ex, $" OnClose?.Invoke();;执行异常");
            }
        }

        private void Client_ServerConnected(object sender, EventArgs e)
        {
            try
            {
                OnConnect.Invoke(true);
            }
            catch (Exception ex)
            {
                LogHelper.Log(LogDefine.LogError, ex, $"新连接 执行异常");
            }
        }

        private void Client_MessageReceived(object sender, MessageReceivedEventArgs e)
        {
            try
            {
                if (OnReceive != null)
                {
                    var span = e.Data.AsSpan();
                    CommondPC cmd = new CommondPC();

                    cmd.Key = (CommondKey)BitConverter.ToInt32(e.Data, 0);
                    int size = BitConverter.ToInt32(e.Data, 4);
                    if (size > 0)
                    {
                        cmd.Data = new byte[e.Data.Length - 8];
                        Array.Copy(e.Data, 8, cmd.Data, 0, cmd.Data.Length);
                    }
                    OnReceive.Invoke(cmd);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Log(LogDefine.LogError, ex, $"收到数据 执行异常");
            }
        }






        public bool Connected()
        {
            return client.Connected;
        }

        public void SendData(Enum main)
        {
            SendData(main, null);
        }

        public void SendData<T>(Enum main, T value)
        {
            byte[] body = value?.ToJsonByte();
            SendData(main, body);
        }


        public void SendData(Enum main, byte[] body)
        {
            List<byte> sendData = new List<byte>();
            sendData.AddRange(BitConverter.GetBytes((int)(object)main));
            if (body != null)
            {
                sendData.AddRange(BitConverter.GetBytes(body.Length));
                sendData.AddRange(body);
            }
            else
            {
                sendData.AddRange(BitConverter.GetBytes(0));
            }
            SendData(sendData.ToArray());
        }

        public void SendData(byte[] data)
        {
            if (Connected())
            {
                try
                {
                    client.SendAsync(data);

                }
                catch (Exception ex)
                {
                    LogHelper.Log(LogDefine.LogError, ex, $"发送数据异常,data.Length={data.Length}");
                }
            }
        }

        public void Close()
        {
            try
            {
                client.Stop();
            }
            catch (Exception ex)
            {
                LogHelper.Log(LogDefine.LogError, ex, $"关闭异常");
            }
        }

        public async Task Connect()
        {
            if (Connected())
            {
                LogHelper.Log(LogDefine.LogVerbose, " Connect 是已连接");
                return;
            }

            try
            {
                LogHelper.Log(LogDefine.LogVerbose, $"正在连接");
                await client.StartWithTimeoutAsync(5);
            }
            catch (Exception ex)
            {
                LogHelper.Log(LogDefine.LogError, ex, $" OnConnect?.Invoke(state);执行异常,state={false}");
            }
        }


        public void Dispose()
        {
            if (client != null)
            {
                client.MessageReceived -= Client_MessageReceived;
                client.ServerConnected -= Client_ServerConnected;
                client.ServerDisconnected -= Client_ServerDisconnected;
                client = null;
            }
        }
    }
}
